#include "../../ExEngine/math/matrix.h"

#include "../../ExEngine/physics/actor.h"
#include "../../ExEngine/physics/physics.h"
#include "../../ExEngine/common/format.h"
#include "../../ExEngine/common/util.h"
#include "../../ExEngine/engine/engine.h"
#include "../../ExEngine/engine/object.h"
#include "../../ExEngine/engine/camera.h"
#include "../../ExEngine/engine/bsp.h"
#include "../../ExEngine/render/d3d_mesh.h"
#include "../../ExEngine/render/d3d.h"
#include "../../ExEngine/sound/dsound.h"

#include "level.h"
#include "player.h"

#include "crate.h"
#include "ent_deathtrigger.h"
#include "ent_cameratoggle.h"
#include "ent_fallbridge.h"
#include "ent_slidedoor.h"
#include "../game/core.h"

/**********************************************************************
 *
 **********************************************************************/


CLevel::CLevel() : CObject()
{
	m_pBSP = NULL;
	
	pSceneLightB = NULL;
	pTorchLight = NULL;
}
HRESULT gLoadObjectHandler(CBSP* pMap, string& name, Matrix4f& transform)
{
	if(name.equals("player")) {
		Game::g_Player->setPosition(transform.Translation());
		Game::g_Checkpoint = transform.Translation();Vector3f(28.4,11.1,15.6);//transform.Translation();
	}
	else 
	if(name.equals("crate")) {

		CCrate *pCrate = EE_NEW CCrate();
		CEngine::GetInstance()->RegisterObject(pCrate);

		pCrate->SetTransform(transform);
		pCrate->Create();
		
	}
	else 
	if(name.equals("camera_toggle")) {

		CCameraToggle* pCameraToggle = EE_NEW CCameraToggle();
		CEngine::GetInstance()->RegisterObject(pCameraToggle);

		pCameraToggle->SetTransform(transform);
		pCameraToggle->Create();
		
	}
	else 
	if(name.equals("death_trigger")) {

		CDeathTrigger* pDeathTrigger = EE_NEW CDeathTrigger();
		CEngine::GetInstance()->RegisterObject(pDeathTrigger);

		pDeathTrigger->SetTransform(transform);
		pDeathTrigger->Create();
		
	}
	else 
	if(name.equals("fall_bridge")) {

		CFallBridge* pFallBridge = EE_NEW CFallBridge();
		CEngine::GetInstance()->RegisterObject(pFallBridge);

		pFallBridge->SetTransform(transform);
		pFallBridge->Create();
	}
	else 
	if(name.equals("slide_door")) {

		CSlideDoor* pSlideDoor = EE_NEW CSlideDoor();
		CEngine::GetInstance()->RegisterObject(pSlideDoor);

		pSlideDoor->SetTransform(transform);
		pSlideDoor->Create();
	}
return 0;
}

HRESULT CLevel::LoadFile(const string& filename)
{	
return 0;	
}

HRESULT CLevel::Create()
{	
	
	CEngine::GetInstance()->GetRenderer()->SetFogParamters(FogData());
	if(game_DebugLevel)
		CEngine::GetInstance()->CreateLevel("debuglevel.wld", gLoadObjectHandler, &m_pBSP);
	else
		CEngine::GetInstance()->CreateLevel("Level01.wld", gLoadObjectHandler, &m_pBSP);

	SunData sun;
	sun.m_Direction = D3DXVECTOR3(0,-1,1);
	sun.m_Ambience = D3DXVECTOR3(0.3,.3,.3);
	sun.m_Diffuse = D3DXVECTOR3(0.8,.7,.4);
	//sun.m_IsActive = false;

	CEngine::GetInstance()->GetRenderer()->SetSunParameters(sun);
	
	CActor::ActorData data;
	data.initalTransform = m_transform;
	data.mass = 1.0f;
	data.friction = 0.2f;
	data.restitution = 0.1f;

	if(game_DebugLevel) {
		if(FAILED(CEngine::GetInstance()->GetPhysics()->CreateWorld("DebugLevel.hkx", (void**)&m_pPhysics)))
		{
			Release();
			return E_FAIL;
		}
	}
	else {
		if(FAILED(CEngine::GetInstance()->GetPhysics()->CreateWorld("Level01.hkx", (void**)&m_pPhysics)))
		{
			Release();
			return E_FAIL;
		}
	}
	return S_OK;
}

HRESULT CLevel::Release()
{	
	HRESULT result = S_OK;
	if(m_pModel)
	{
		m_pModel = NULL;
	}
	if(m_pPhysics)
	{
		CPhysics* pPhysics = CEngine::GetInstance()->GetPhysics();
		if(FAILED(pPhysics->ReleaseActor(m_pPhysics)))
			result = E_FAIL;
		m_pPhysics = NULL;
	}
	
	if(pSceneLightB)
	{
		pSceneLightB->Release();
		pSceneLightB = NULL;
	}

	return result;
}

void CLevel::Update(const float dt)
{	
	//gSceneLights.pTorchLight->SetPosition(CEngine::GetInstance()->GetCamera()->getPosition());	
	//gSceneLights.pTorchLight->SetLightCoefficents(0.75,1.0,0.2);
	//gSceneLights.pTorchLight->SetAttenuation(0.1);

	if(m_pPhysics)
		m_transform = m_pPhysics->GetTransform();
}

void CLevel::Draw()
{	
	m_pBSP->Draw(CEngine::GetInstance()->GetRenderer()->GetViewOrrientation());

}